// Generic stack class version 2
// This stack class can handle any datatype.
// Added option to create a size for the stack.
// Added IsEmpty function to tell us if the stack is empty.
// Added IsFull function to tell us if the stack is full.
// Added Peek to look at a item without popping it from the stack.
// By Ben

#include <iostream>
using namespace std;

template<typename T>
class TStack{
private:
	T *_stack;
	int _tos;
	int s_size;
public:

	TStack(int nSize){
		//Reset stack size.
		this->_tos = 0;
		this->s_size = nSize;
		this->_stack = new T[nSize];
	}

	~TStack(){
		this->_tos = 0;
		delete _stack;
	}

	void Push(T item){
		//Push item on the stack
		_stack[this->_tos] = item;
		//INC stack size.
		this->_tos++;
	}

	void Pop(){
		//DEC stack size.
		this->_tos--;
	}

	T Top(){
		//Return item on stack.
		return this->_stack[this->_tos];
	}

	T Peek(){
		//Return an item with out pooping the item of the stack.
		return this->_stack[this->_tos - 1];
	}

	bool IsEmpty(){
		//Return true if stack is empty otherwise false is returned.
		return this->_tos == 0;
	}

	bool IsFull(){
		//Return true if stack is full otherwise false is returned.
		return this->_tos >= this->s_size;
	}
};
//End stack class.

int main(){

	TStack<int>stk(11);
	int x = 0;

	//Push INT's 0 to 10 on the stack.
	while (x <= 10){
		std::cout << "Pushing item on the stack " << x << endl;
		stk.Push(x);
		x++;
	}

	std::cout << "Stack is full: " << stk.IsFull() << endl;
	std::cout << endl;

	std::cout << endl;
	//Pop off the items on the stack.
	while (!stk.IsEmpty()){
		stk.Pop();
		std::cout << "Popping item off the stack " << stk.Top() << endl;
		x++;
	}

	std::cout << "Stack is Empty: " << stk.IsEmpty() << endl;
	std::cout << endl;

	//system("pause");
	return 0;
}